/**
 * 
 */
package com.nari.heatshare.service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import com.nari.coreframe.service.GenericServiceImpl;
import com.nari.heatshare.dao.IAssignMeterDao;
import com.nari.heatshare.dao.IAssignMeterDataGatherDao;
import com.nari.heatshare.dao.IAssignMeterDataStatisticsDao;
import com.nari.heatshare.dao.IGprsUploadTraceDao;
import com.nari.heatshare.dao.IHeatMeterDataGatherDao;
import com.nari.heatshare.dao.springjdbc.IAssignMeterDataJdbcDao;
import com.nari.heatshare.model.IAssignMeterDataGather;
import com.nari.heatshare.model.IAssignMeterDataStatistics;
import com.nari.heatshare.model.IGprsUploadTrace;
import com.nari.heatshare.utils.queryvo.AssignMeterDataStatisExtendQuery;
import com.nari.platform.model.PageCond;
import com.nari.platform.model.ResponseMsg;
import com.nari.platform.model.ResultWithPageCond;
import com.nari.platform.utils.CommercialHighPrecisionArith;

/**
 * 
 * @author yw
 * @date 2013-9-24
 */
public class AssignMeterDataStatisticsServiceImpl extends GenericServiceImpl<IAssignMeterDataStatistics, String>
		implements IAssignMeterDataStatisticsService {
	private IAssignMeterDao iAssignMeterDao;
	private IAssignMeterDataGatherDao iAssignMeterDataGatherDao;
	private IHeatMeterDataGatherDao iHeatMeterDataGatherDao;
	private IGprsUploadTraceDao iGprsUploadTraceDao;
	private IAssignMeterDataJdbcDao iAssignMeterDataJdbcDao;

	/**
	 * 分页查询分配表数据上传的任务批次统计
	 * 分配表数据上传的任务批次条件：集中器号、抄表日期
	 * @param concentratorNo 集中器号
	 * @param startDate 抄表日期起始日期
	 * @param endDate 抄表日期结束日期
	 * @param pageCond
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2013-10-25
	 */
	public ResultWithPageCond<IAssignMeterDataStatistics> queryMeterDataStatisPage(String concentratorNo, 
			Date startDate, Date endDate, PageCond pageCond) throws Exception {
		IAssignMeterDataStatisticsDao iAssignMeterDataStatisticsDao = (IAssignMeterDataStatisticsDao) this.getiGenericDao();
		return iAssignMeterDataStatisticsDao.queryMeterDataStatisPage(concentratorNo, startDate, endDate, pageCond);
	}
	
	/**
	 * 删除GPRS批次上传数据
	 * @param meterDataStatisUID
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2013-12-2
	 */
	public ResponseMsg deleteMeterDataUploadBatch(String meterDataStatisUID) throws Exception {
		//查询上传任务统计
		IAssignMeterDataStatistics meterDataStatis = this.getiGenericDao().queryEntityById(meterDataStatisUID);
		//删除定点上传、人工平滑的分配表数据
		iAssignMeterDataGatherDao.deleteMeterDataUploadBatch(meterDataStatis.getConcentratorNo(), meterDataStatis.getRecordTime(), 2, 0);
		//删除GPRS上传痕迹信息
		IGprsUploadTrace uploadTrace = iGprsUploadTraceDao.queryTraceInfoByBatchUID(meterDataStatisUID, 1);
		if(uploadTrace != null) {
			iGprsUploadTraceDao.deleteTraceFileByUID(uploadTrace.getId());
		}
		//删除批次删除的热量表数据
//		iHeatMeterDataGatherDao.deleteMeterDataUploadBatch(meterDataStatis.getRecordTime(), 2);
		//删除上传任务统计
		this.getiGenericDao().deleteEntityById(meterDataStatisUID);
		return ResponseMsg.getInstance(true, "");
	}
	
	/**
	 * 批次新增分配表上传任务数据
	 * @param meterDataList
	 * @param concentratorNo
	 * @param recordTime
	 * @param dataFileUID 掌机文件UID
	 * @param dataType 数据类型
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2015-1-15
	 */
	public ResponseMsg saveMeterDataBatch(List<IAssignMeterDataGather> meterDataList, 
			String concentratorNo, Date recordTime, String dataFileUID, 
			Integer dataType) throws Exception {
		if(meterDataList!=null && meterDataList.size()>0) {
			//保存分配表批次数据
			int batchUploadSaved = this.saveAssignMeterDataUpload(meterDataList, dataFileUID);
			//返回批处理保存的数据有多少
			//批次数据发生更新的条件下执行批次任务信息的更新
			String statisUID = null;
			if(batchUploadSaved > 0) {//保存的数大于0
				//更新任务统计信息
				statisUID = this.saveOrUpdateAmdStatis(concentratorNo, recordTime,meterDataList.size());//此时保存此任务信息,将上传数定义为注册数
			} else {
				IAssignMeterDataStatistics meterDataStatis = this.queryStatisByUploadMission(concentratorNo, recordTime);
				if(meterDataStatis != null) {
					statisUID = meterDataStatis.getId();
				}
			}
			//定点上传数据做GPRS痕迹追踪
			if(dataType!=null && dataType==2) {
				//生成GPRS上传痕迹信息
				iGprsUploadTraceDao.saveAmdGprsUploadTraceFile(meterDataList, statisUID, concentratorNo, recordTime);
			}
			return ResponseMsg.getInstance(true, Integer.toString(batchUploadSaved));
		}
		return ResponseMsg.getInstance(false, "分配表数据为空，无法保存批次数据！");
	}
	
	/**
	 * 保存接口上传的分配表数据，并返回成功保存的数据条目数
	 * @param meterDataList
	 * @param dataFileUID 掌机文件UID
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2015-1-15
	 */
	private int saveAssignMeterDataUpload(List<IAssignMeterDataGather> meterDataList, 
			String dataFileUID) throws Exception {
		int savedCounter = 0;
		if(meterDataList!=null && meterDataList.size()>0) {
			for(IAssignMeterDataGather meterData: meterDataList) {
				//根据需要设置掌机文件关联
				if(dataFileUID!=null && !"".equals(dataFileUID)) {
					meterData.setDataFileID(dataFileUID);
				}
				ResponseMsg rmsg = iAssignMeterDataGatherDao.saveOrUpdateMeterData(meterData);
				if(rmsg.isSuccess()) {
					savedCounter++;
					//强制更新数据到数据库，便于执行数据去重处理、批次统计分析
					iAssignMeterDataGatherDao.flush();
				}
			}
		}
		return savedCounter;
	}
	
	/**
	 * 根据上传任务标识(集中器号、抄表日期)查询分配表数据统计结果
	 * @param concentratorNo
	 * @param recordTime
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2013-11-13
	 */
	public IAssignMeterDataStatistics queryStatisByUploadMission(String concentratorNo, 
			Date recordTime) throws Exception {
		IAssignMeterDataStatisticsDao iAssignMeterDataStatisticsDao = (IAssignMeterDataStatisticsDao) this.getiGenericDao();
		return iAssignMeterDataStatisticsDao.queryStatisByUploadMission(concentratorNo, recordTime);
	}
	
	/**
	 * 新增或更新分配表数据的任务采集信息
	 * 任务标识字段：集中器号、抄表日期
	 * @param concentratorNo
	 * @param recordTime
	 * @return 返回任务批次的唯一标识码UID
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2015-1-17
	 */
	public String saveOrUpdateAmdStatis(String concentratorNo, Date recordTime) throws Exception {
		//查询批次任务数据
		//先查询是否存在,用于更新
		IAssignMeterDataStatistics meterDataStatis = this.queryStatisByUploadMission(concentratorNo, recordTime);
		if(meterDataStatis == null) {
			meterDataStatis = new IAssignMeterDataStatistics();
			//集中器号
			meterDataStatis.setConcentratorNo(concentratorNo); 
			//抄表时间
			meterDataStatis.setRecordTime(recordTime); 
		}
		//批次任务的上传时间，取批次数据中的最大值
		Date readTime = iAssignMeterDataGatherDao.queryReadTime4BatchUpload(concentratorNo, recordTime);
		meterDataStatis.setReadTime(readTime);
		//统计该批次已完成的上传数(注册数的问题)
		int uploadCount = iAssignMeterDataGatherDao.countMeterDataNumByUploadBatch(concentratorNo, recordTime);
		meterDataStatis.setUploadCount(uploadCount);
		//集中器下挂载的分配表个数
		int assignMeterNum = iAssignMeterDao.countMeterSumByConcentratorNo(concentratorNo);
		meterDataStatis.setAssignMeterCount(assignMeterNum);
		//成功上传数
		int saveSuccessCount = iAssignMeterDataJdbcDao.countSuccessUploadNumReferBatch(concentratorNo, 
				recordTime, readTime, null); //统计所有采集方式上传的热表数据
		meterDataStatis.setSaveSuccessCount(saveSuccessCount);
		//计算集中器的上传率
		double uploadPercent = 0;
		if(assignMeterNum > 0) {
			uploadPercent = CommercialHighPrecisionArith.divide(saveSuccessCount * 100, assignMeterNum, 5);
		}
		meterDataStatis.setUploadPercent(uploadPercent);
		//最后更新时间
		meterDataStatis.setUpdateTime(new Date());
		this.getiGenericDao().saveOrUpdateEntity(meterDataStatis);
		//返回任务统计信息的唯一标识
		return meterDataStatis.getId();
	}
	
	/**
	 * 新增或更新分配表数据的任务采集信息(增加注册数,将注册数改为上传数,由上传最后决定)
	 * 任务标识字段：集中器号、抄表日期
	 * @param concentratorNo
	 * @param recordTime
	 * @return 返回任务批次的唯一标识码UID
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2015-1-17
	 */
	public String saveOrUpdateAmdStatis(String concentratorNo, Date recordTime,int uploadCount) throws Exception {
		//查询批次任务数据
		//先查询是否存在,用于更新
		IAssignMeterDataStatistics meterDataStatis = this.queryStatisByUploadMission(concentratorNo, recordTime);
		if(meterDataStatis == null) {
			meterDataStatis = new IAssignMeterDataStatistics();
			//集中器号
			meterDataStatis.setConcentratorNo(concentratorNo); 
			//抄表时间
			meterDataStatis.setRecordTime(recordTime); 
		}
		//批次任务的上传时间，取批次数据中的最大值
		Date readTime = iAssignMeterDataGatherDao.queryReadTime4BatchUpload(concentratorNo, recordTime);
		meterDataStatis.setReadTime(readTime);
		//统计该批次已完成的上传数(注册数的问题)
//		int uploadCount = iAssignMeterDataGatherDao.countMeterDataNumByUploadBatch(concentratorNo, recordTime);
		meterDataStatis.setUploadCount(uploadCount);
		//集中器下挂载的分配表个数
		int assignMeterNum = iAssignMeterDao.countMeterSumByConcentratorNo(concentratorNo);
		meterDataStatis.setAssignMeterCount(assignMeterNum);
		//成功上传数
		int saveSuccessCount = iAssignMeterDataJdbcDao.countSuccessUploadNumReferBatch(concentratorNo, 
				recordTime, readTime, null); //统计所有采集方式上传的热表数据
		meterDataStatis.setSaveSuccessCount(saveSuccessCount);
		//计算集中器的上传率
		double uploadPercent = 0;
		if(assignMeterNum > 0) {
			uploadPercent = CommercialHighPrecisionArith.divide(saveSuccessCount * 100, assignMeterNum, 5);
		}
		double k = 1;
		if((k=uploadPercent/100)>1) {
			uploadPercent = uploadPercent/(k+1);//如果一天多次上传的情况,取上传平均数
		}
		meterDataStatis.setUploadPercent(uploadPercent);
		//最后更新时间
		meterDataStatis.setUpdateTime(new Date());
		this.getiGenericDao().saveOrUpdateEntity(meterDataStatis);
		//返回任务统计信息的唯一标识
		return meterDataStatis.getId();
	}
	
	/**
	 * 查询分配表数据上传批次的痕迹信息
	 * @param statisList
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2014-5-8
	 */
	public Map<String, String> queryMeterDataStatisReferTrace(List<IAssignMeterDataStatistics> 
			statisList) throws Exception {
		List<String> batchStatisUIDList = null;
		if(statisList!=null && statisList.size()>0) {
			batchStatisUIDList = new ArrayList<String>();
			for(IAssignMeterDataStatistics meterDataStatis: statisList) {
				batchStatisUIDList.add(meterDataStatis.getId());
			}
		}
		return iGprsUploadTraceDao.queryReferBatchStatisMap(batchStatisUIDList, 1);
	}
	
	/**
	 * 根据分配表数据批次列表查询其对应的档案资料扩展信息
	 * @param amdStatisList
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2015-1-25
	 */
	public Map<String, AssignMeterDataStatisExtendQuery> queryAmdStatisExtend(List<IAssignMeterDataStatistics> 
			amdStatisList) throws Exception {
		StringBuffer meterDataStatisUIDList = new StringBuffer("");
		if(amdStatisList!=null && amdStatisList.size()>0) {
			for(int index=0; index<amdStatisList.size(); index++) {
				meterDataStatisUIDList.append(amdStatisList.get(index).getId());
				if(index < amdStatisList.size()-1) {
					meterDataStatisUIDList.append(",");
				}
			}
		}
		return this.iAssignMeterDataJdbcDao.queryAmdStatisExtend(meterDataStatisUIDList.toString());
	}

	/**
	 * @return the iAssignMeterDao
	 */
	public IAssignMeterDao getiAssignMeterDao() {
		return iAssignMeterDao;
	}

	/**
	 * @param iAssignMeterDao the iAssignMeterDao to set
	 */
	public void setiAssignMeterDao(IAssignMeterDao iAssignMeterDao) {
		this.iAssignMeterDao = iAssignMeterDao;
	}

	/**
	 * @return the iAssignMeterDataGatherDao
	 */
	public IAssignMeterDataGatherDao getiAssignMeterDataGatherDao() {
		return iAssignMeterDataGatherDao;
	}

	/**
	 * @param iAssignMeterDataGatherDao the iAssignMeterDataGatherDao to set
	 */
	public void setiAssignMeterDataGatherDao(
			IAssignMeterDataGatherDao iAssignMeterDataGatherDao) {
		this.iAssignMeterDataGatherDao = iAssignMeterDataGatherDao;
	}

	/**
	 * @return the iHeatMeterDataGatherDao
	 */
	public IHeatMeterDataGatherDao getiHeatMeterDataGatherDao() {
		return iHeatMeterDataGatherDao;
	}

	/**
	 * @param iHeatMeterDataGatherDao the iHeatMeterDataGatherDao to set
	 */
	public void setiHeatMeterDataGatherDao(
			IHeatMeterDataGatherDao iHeatMeterDataGatherDao) {
		this.iHeatMeterDataGatherDao = iHeatMeterDataGatherDao;
	}

	/**
	 * @return the iGprsUploadTraceDao
	 */
	public IGprsUploadTraceDao getiGprsUploadTraceDao() {
		return iGprsUploadTraceDao;
	}

	/**
	 * @param iGprsUploadTraceDao the iGprsUploadTraceDao to set
	 */
	public void setiGprsUploadTraceDao(IGprsUploadTraceDao iGprsUploadTraceDao) {
		this.iGprsUploadTraceDao = iGprsUploadTraceDao;
	}

	/**
	 * @return the iAssignMeterDataJdbcDao
	 */
	public IAssignMeterDataJdbcDao getiAssignMeterDataJdbcDao() {
		return iAssignMeterDataJdbcDao;
	}

	/**
	 * @param iAssignMeterDataJdbcDao the iAssignMeterDataJdbcDao to set
	 */
	public void setiAssignMeterDataJdbcDao(
			IAssignMeterDataJdbcDao iAssignMeterDataJdbcDao) {
		this.iAssignMeterDataJdbcDao = iAssignMeterDataJdbcDao;
	}
	
}
